package com.jetpackframework.routerview;

import android.text.TextUtils;
import android.util.ArrayMap;

import com.blankj.utilcode.util.StringUtils;
import com.jetpackframework.Reflector;
import com.jetpackframework.arouter.RouterInitialization;
import com.jetpackframework.ioc.EventClassUtil;
import com.jetpackframework.ioc.IEventClass;
import com.jetpackframework.ioc.IViewBind;
import com.jetpackframework.ioc.LayoutUtil;

public class BaseRouterViewLoader implements RouterViewLoader {
    private RouterViewLoader parent;
    private String moudleName;
    private ArrayMap<Integer,IViewBind> cacheViewBinding;
    private ArrayMap<String,IEventClass> cacheViewEvents;
    private ArrayMap<String,String> cacheARouters;


    public BaseRouterViewLoader(String moudleName, RouterViewLoader parent) {
        this.parent = parent;
        this.moudleName = moudleName;
        cacheViewBinding = new ArrayMap<>();
        cacheViewEvents = new ArrayMap<>();
        cacheARouters = new ArrayMap<>();
    }


    @Override
    public <V extends IViewBind> V loadLayoutEvent(int r2ResId) {
        V viewBind = (V) cacheViewBinding.get(r2ResId);
        if (viewBind != null){
            return viewBind;
        }
        if (parent != null){
            viewBind = parent.loadLayoutEvent(r2ResId);
            if (viewBind != null){
                return viewBind;
            }
        }
        try {
            if (moudleName != null) {
                LayoutUtil layoutUtil = Reflector.on("com." + moudleName + ".layout.LayoutInflaterUtils").constructor().newInstance();
                viewBind = layoutUtil.getViewBind(r2ResId);
                if (viewBind != null) {
                    cacheViewBinding.put(r2ResId, viewBind);
                    return viewBind;
                }
            }
        } catch (Exception e) {
        }
        return null;
    }

    @Override
    public <E extends IEventClass> E loadEvent(Class simpleClass) {
        E event = (E) cacheViewEvents.get(simpleClass.getPackage().getName()+"."+simpleClass.getSimpleName());
        if (event != null){
            return event;
        }
        if (parent != null){
            event = parent.loadEvent(simpleClass);
            if (event != null){
                return event;
            }
        }
        try {
            if (moudleName != null){

                EventClassUtil eventClassUtil = Reflector.on("com."+moudleName+".layoutevent.EventInflaterUtils").constructor().newInstance();
                event = eventClassUtil.getEventClass(simpleClass);
                if (event != null) {
                    cacheViewEvents.put(simpleClass.getPackage().getName() + "." + simpleClass.getSimpleName(), event);
                    return event;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String loadARouter(String arouterStr) {
        String arouter = cacheARouters.get(arouterStr);
        if (!TextUtils.isEmpty(arouter)){
            return arouter;
        }
        if (parent != null){
            arouter = parent.loadARouter(arouterStr);
            if (!TextUtils.isEmpty(arouter)){
                return arouter;
            }
        }
        if (moudleName != null){
            try {
                RouterInitialization routerInit = Reflector.on("com."+moudleName+".arouter."+StringUtils.upperFirstLetter(moudleName)+"Router").constructor().newInstance();
                arouter = routerInit.getRouter(arouterStr);
                if (!TextUtils.isEmpty(arouter)){
                    cacheARouters.put(arouterStr,arouter);
                    return arouter;
                }
            } catch (Exception e) {
            }
        }
        return null;
    }

    @Override
    public void clearCache() {
        cacheViewBinding.clear();
        cacheViewEvents.clear();
        cacheARouters.clear();
        if (parent != null){
            parent.clearCache();
        }
    }

    @Override
    public RouterViewLoader getParent() {
        return parent;
    }

}
